package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.kafka.WmNewsMessageConstants;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.AutoDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.utils.common.WmThreadLocalUtil;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsServer;
import com.heima.wemedia.service.WmNewsTaskService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsServerImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsServer {

@Autowired
    WmNewsMaterialMapper wmNewsMaterialMapper;
@Autowired
    WmMaterialMapper wmMaterialMapper;
@Autowired
    WmNewsAutoScanService wmNewsAutoScanService;
@Autowired
    WmNewsTaskService wmNewsTaskService;
@Autowired
    KafkaTemplate kafkaTemplate;
    @Override
    public ResponseResult findList(WmNewsPageReqDto dto) {
        if (dto==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        ////分页参数检查
            dto.checkParam();

        LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();


        //状态精确查询
        if (dto.getStatus()!=null) {
            wrapper.eq(WmNews :: getStatus,dto.getStatus());
        }
        //频道
        if (dto.getChannelId()!=null) {
            wrapper.eq(WmNews ::getChannelId,dto.getChannelId());
        }
        //时间范围
        if (dto.getBeginPubdate()!=null && dto.getEndPubdate()!=null) {
            wrapper.between(WmNews :: getPublishTime,dto.getBeginPubdate(),dto.getEndPubdate());
        }
        //关键字
        if (dto.getKeyword()!=null) {
              wrapper.like(WmNews ::getTitle,dto.getKeyword());
        }
        //当前用户
        if (WmThreadLocalUtil.getUser().getId()!=null){
            wrapper.eq(WmNews ::getUserId, WmThreadLocalUtil.getUser().getId());
        }

        //时间倒叙
        wrapper.orderByDesc(WmNews::getCreatedTime);
        //分页条件查询
        IPage<WmNews> ipage=new Page<>(dto.getPage(),dto.getSize());



        IPage<WmNews> page = page(ipage, wrapper);

        ResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
       result.setData(page.getRecords());

        return result;
    }

    @Override
    //发布文章
    public ResponseResult submitNews(WmNewsDto dto) throws Exception {
        //判断参数
        if (dto.getContent()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (dto.getType()==-1){
           dto.setType(null);
        }
        //复制信息
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);

        List<String> images = dto.getImages();
        if (images!=null && images.size() > 0){
            //将集合转换为字符串,并用字符隔开
            String image = StringUtils.join(images, ",");
            wmNews.setImages(image);
        }
        //执行修改和保存
        saveorUpdateNews(wmNews);
        //2.如果是草稿
        if (dto.getStatus()==0){
            return ResponseResult.okResult(null);
        }
        //4.关联中间表，操作wm_news_marterial表
        //4.0 要从内容中把图片给抽取出来
        List imagelist = chouquImageList(wmNews);
        //4.1 内容中图片与文章的关系
        contentImageToNews(wmNews,imagelist,(short)0);

        //4.2 封面图片与文章的关系
        fengmianImageToNews(wmNews,dto,imagelist,(short)1);
        //自动审核
      //  wmNewsAutoScanService.autoScanWmNews(wmNews.getId());
        //定时延迟
        wmNewsTaskService.addNewsToTask(wmNews.getId(),wmNews.getPublishTime());
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    /**
     * 抽取的第四个方法，关联封面图片与文章的关系，操作中间表
     *  如果封面类型是自动的话，从文章内容中图片进行操作
     *      如果文章内容图片个数大于1，小于3的话，则认为单图
     *      如果文章内容图片个数大于等于3的话，则认为多图
     *       如果文章内容图片个数，则认为是无图
     *
     * @param wmNews
     * @param type
     */
    private void fengmianImageToNews(WmNews wmNews,WmNewsDto dto,List imageList, short type) {
        //1.获取封面图片
        List<String> images = dto.getImages();

        //自动
        if(dto.getType()==null){
            if(imageList.size()>=1 && imageList.size()<3){
                //取出第一张图片作为封面
                images= (List<String>) imageList.stream().limit(1).collect(Collectors.toList());
                //单图设置类型
                wmNews.setType((short) 1);
            }else if(imageList.size()>=3){
                images= (List<String>) imageList.stream().limit(3).collect(Collectors.toList());
                //多图设置类型
                wmNews.setType((short) 3);
            }else{
                wmNews.setType((short) 0);
            }

            wmNews.setImages(StringUtils.join(images, ","));
            updateById(wmNews);
        }
        //否则，直接插入到中间表中
        saveNewsMaterial(wmNews, type, images);
    }

    /**
     * 第三个抽取方法，关联内容中的图片与文章的关系，操作中间表
     * @param wmNews 文章实体
     * @param imageList  内容中抽取的图片集合,图片地址集合
     * @param type  引用类型，0表示内容引用 1表示封面引用
     */
    private void contentImageToNews(WmNews wmNews, List imageList , short type) {
        saveNewsMaterial(wmNews, type, imageList);
    }
//第四个
    private void saveNewsMaterial(WmNews wmNews, short type, List imageList) {
        if (imageList!=null && imageList.size() > 0) {
            //根据地址差素材
      //   wmNewsMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl,imageList));
            List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, imageList));
            //2.要从素材集合中只抽取出相对应的id集合
            List<Integer> ids = wmMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
            /**
             * 参数1表示素材id集合
             * 参数2表示文章id
             * 参数3表示引用类型
             */
            wmNewsMaterialMapper.saveRelations(ids,wmNews.getId(),type);



        }
    }

    //抽取图片
    private List chouquImageList(WmNews wmNews) {
        ArrayList arrayList = new ArrayList<>();
        String content = wmNews.getContent();
       List<Map> list= JSON.parseArray(content, Map.class);
        for (Map map : list) {
            if(map.get("type").equals("image")){
                String value = (String) map.get("value");
                arrayList.add(value);
            }
        }
        return arrayList;
    }


    //执行修改或者保存方法
    private void saveorUpdateNews(WmNews wmNews) {
        //补全属性
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());
        wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
        //判断是否存在id,不存在删除关联素材,修改文章
        if (wmNews.getId()!=null) {
            LambdaQueryWrapper<WmNewsMaterial> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(WmNewsMaterial ::getNewsId,wmNews.getId());
            wmNewsMaterialMapper.delete(wrapper);
            updateById(wmNews);
        }else {
            save(wmNews);
        }
    }





//上下架

    @Override
    public ResponseResult downUp(WmNewsDto dto) {
        WmNews wmNews = getById(dto.getId());
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
       if ( !wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){
           throw new RuntimeException("当前文章不是发布状态,不能上下架");
       }
       if (dto.getEnable()!=null){
           wmNews.setEnable(dto.getEnable());
           updateById(wmNews);
       }
       //发送消息通知article修改文章配置
        if (wmNews.getArticleId()!=null) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("articleId",wmNews.getArticleId());
            map.put("enable",dto.getEnable());
            kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC,JSON.toJSONString(map));

        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
//媒体审核查询
    @Override
    public ResponseResult list_vo(AutoDto dto) {
//        if (dto == null) {
//            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
//        }
        IPage<WmNews> page=new Page<>(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();
        wrapper.orderByDesc(WmNews ::getCreatedTime);
        wrapper.like(WmNews ::getTitle,dto.getTitle());
       // wrapper.eq(WmNews ::getStatus,dto.getStatus());
      page= page(page,wrapper);
       List<WmNews> list = list(wrapper);

        ResponseResult result= new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
        result.setData(page.getRecords());
        return result.ok(list);
    }
//文章详情
    @Override
    public ResponseResult one_voId(Integer id) {

       LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();
       wrapper.eq(WmNews::getId,id);
        WmNews wmNews = getOne(wrapper);
        ResponseResult result = new ResponseResult();
        result.setData(wmNews);
        return result;
    }
//审核失败
    @Override
    public ResponseResult auth_fail(AutoDto dto) {

        LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(WmNews::getId,dto.getId());
        WmNews wmNews = getOne(wrapper);
        wmNews.setStatus((short) 2);
        updateById(wmNews);
        ResponseResult result = new ResponseResult();
        result.setData(wmNews);
        return result;
    }
//审核成功
    @Override
    public ResponseResult auth_pass(AutoDto dto) {
        LambdaQueryWrapper<WmNews> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(WmNews::getId,dto.getId());
        WmNews wmNews = getOne(wrapper);
        wmNews.setStatus((short) 9);
        ResponseResult result = new ResponseResult();
        result.setData(wmNews);
        return result;
    }
}
